<!DOCTYPE html>
<html lang="zh">
<head>
    <!--
        页面：博客详情页（AiBlog/blog-detail.html）
        作用：
        - 展示单篇博客详情（标题/作者/时间/阅读量/标签/正文）
        - 右侧显示相关文章与公众号二维码
        - 数据来源：./Blogs.json（本地静态），../config.json（站点配置）
        - UI：TailwindCSS + 自定义配置
    -->
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>博客详情 - lumina AI</title>
    <script src="../assets/js/tailwindcss.js"></script>
    <script src="https://cdn.tailwindcss.com"></script>
    <script>
        // Tailwind 运行时配置：扩展主题色、圆角与动画关键帧
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#FFE45C',
                        secondary: '#FFE45C',
                        accent: '#10B981'
                    },
                    borderRadius: {
                        'none': '0px',
                        'sm': '2px',
                        DEFAULT: '4px',
                        'md': '8px',
                        'lg': '12px',
                        'xl': '16px',
                        '2xl': '20px',
                        '3xl': '24px',
                        'full': '9999px',
                        'button': '8px'
                    },
                    animation: {
                        'fade-in': 'fadeIn 0.6s ease-in-out',
                        'slide-up': 'slideUp 0.8s ease-out',
                        'bounce-gentle': 'bounceGentle 2s infinite'
                    },
                    keyframes: {
                        fadeIn: {
                            '0%': { opacity: '0' },
                            '100%': { opacity: '1' }
                        },
                        slideUp: {
                            '0%': { transform: 'translateY(30px)', opacity: '0' },
                            '100%': { transform: 'translateY(0)', opacity: '1' }
                        },
                        bounceGentle: {
                            '0%, 100%': { transform: 'translateY(0)' },
                            '50%': { transform: 'translateY(-10px)' }
                        }
                    }
                }
            }
        }
    </script>
    <!-- 字体与全局样式（确保与首页等页面一致的视觉体系） -->
    <link href="../assets/css/google-fonts-pacifico-inter.css" rel="stylesheet">
    <link href="../assets/css/font-awesome.min.css" rel="stylesheet">
    <link href="../assets/css/lemon-milk.css" rel="stylesheet">
    <link href="../assets/css/google-fonts-montserrat.css" rel="stylesheet">
    <link href="../assets/css/BlogsIndex.css" rel="stylesheet">
</head>
<body class="min-h-screen font-['Inter'] scroll-smooth bg-gray-50">
    <!-- 导航栏：与站点其它页面一致的顶部固定导航 -->
    <header class="fixed top-0 left-0 right-0 bg-white/95 backdrop-blur-md z-50 border-b border-gray-100 shadow-sm">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
            <div class="flex items-center gap-3">
                <span class="text-2xl text-black" style="font-family: 'Montserrat', Arial, sans-serif;">lumina AI</span>
            </div>
            
            <!-- 桌面端导航：主要频道入口 -->
            <nav class="hidden md:flex items-center gap-8 justify-center flex-1">
                <a href="../index.html" class="font-medium transition-colors duration-200">主页</a>
                <a href="../AiEntry/index.html" class="text-gray-600 hover:text-[#FFE45C] font-medium transition-colors duration-200">AI词条</a>
                <a href="../AiOpen/index.html" class="text-gray-600 hover:text-[#FFE45C] font-medium transition-colors duration-200">AI开源</a>
                <a href="../AiHardware/index.html" class="text-gray-600 hover:text-[#FFE45C] font-medium transition-colors duration-200">AI硬件</a>
                <a href="../AiPrompts/index.html" class="text-gray-600 hover:text-[#FFE45C] font-medium transition-colors duration-200">指令库</a>
                <a href="./index.html" class="text-[#FFE45C] hover:text-[#FFE45C] font-medium transition-colors duration-200">博客</a>
            </nav>
            
            <!-- 工具区域：社交/语言/用户；移动端菜单按钮在右侧 -->
            <div class="flex items-center gap-4">
                <button class="flex items-center gap-1 text-gray-600 hover:text-secondary hover:bg-gray-100 rounded-lg px-3 py-2 transition-all duration-200">
                    <i class="fab fa-weixin"></i>
                </button>
                <button class="flex items-center gap-1 text-gray-600 hover:text-[#FFE45C] hover:bg-gray-100 rounded-lg px-3 py-2 transition-colors duration-200 active:bg-gray-200">
                    <i class="fas fa-globe"></i>
                </button>
                <button class="flex items-center gap-1 text-gray-600 hover:text-[#FFE45C] hover:bg-gray-100 rounded-lg px-3 py-2 transition-colors duration-200 active:bg-gray-200">
                    <i class="fas fa-user"></i>
                </button>
                <button class="md:hidden w-10 h-10 flex items-center justify-center text-gray-600 hover:text-[#FFE45C] hover:bg-gray-100 rounded-lg transition-colors duration-200 active:bg-gray-200" onclick="toggleMobileMenu()">
                    <i class="fas fa-bars"></i>
                </button>
            </div>
        </div>
        
        <!-- 移动端菜单：通过 common.js 中的 toggleMobileMenu() 控制展开/收起 -->
        <div id="mobileMenu" class="md:hidden hidden bg-white border-t border-gray-100">
            <div class="px-4 py-6 space-y-4">
                <a href="../index.html" class="block text-gray-600 hover:text-[#FFE45C] font-medium py-2">主页</a>
                <a href="../AiEntry/index.html" class="block text-gray-600 hover:text-[#FFE45C] font-medium py-2">AI词条</a>
                <a href="../AiOpen/index.html" class="block text-gray-600 hover:text-[#FFE45C] font-medium py-2">AI开源</a>
                <a href="../AiHardware/index.html" class="block text-gray-600 hover:text-[#FFE45C] font-medium py-2">AI硬件</a>
                <a href="../AiPrompts/index.html" class="block text-gray-600 hover:text-[#FFE45C] font-medium py-2">指令库</a>
                <a href="./index.html" class="block text-[#FFE45C] font-medium py-2">博客</a>
            </div>
        </div>
    </header>

    <main class="pt-16">
        <!-- 面包屑导航 -->
        <section class="bg-white border-b border-gray-200">
            <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-4">
                <nav class="flex items-center space-x-2 text-sm">
                    <a href="../index.html" class="text-gray-500 hover:text-primary transition-colors">
                        <i class="fas fa-home"></i>
                    </a>
                    <i class="fas fa-chevron-right text-gray-300"></i>
                    <a href="./index.html" class="text-gray-500 hover:text-primary transition-colors">博客</a>
                    <i class="fas fa-chevron-right text-gray-300"></i>
                    <span class="text-gray-900 font-medium" id="breadcrumbTitle">博客详情</span>
                </nav>
            </div>
        </section>

        <!-- 主要内容区域：左侧正文（3列） + 右侧边栏（1列） -->
        <section class="py-12">
            <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
                <div class="grid grid-cols-1 lg:grid-cols-4 gap-8">
                    <!-- 左侧博客内容：文章信息与正文 -->
                    <div class="lg:col-span-3">
                        <!-- 博客文章卡片 -->
                        <article class="bg-white rounded-xl p-8 shadow-sm">
                            <!-- 文章头部：分类徽标、发布日期、标题、作者、阅读量 -->
                            <div class="mb-8">
                                <div class="flex items-center gap-2 mb-4">
                                    <span id="articleCategory" class="px-3 py-1 bg-yellow-100 text-yellow-700 text-sm rounded-full">产品思考</span>
                                    <span id="articleDate" class="text-sm text-gray-500">2024-06-01</span>
                                </div>
                                <h1 id="articleTitle" class="text-3xl sm:text-4xl font-bold text-gray-900 mb-4">
                                    AI产品经理成长路线：从入门到精通的完整指南
                                </h1>
                                <div class="flex items-center justify-between">
                                    <div class="flex items-center gap-4">
                                        <div class="flex items-center gap-2">
                                            <div class="w-10 h-10 bg-gradient-to-br from-blue-100 to-blue-200 rounded-full flex items-center justify-center" id="authorAvatar">
                                                <span class="text-blue-600 font-medium text-sm" id="authorInitial">张</span>
                                            </div>
                                            <div>
                                                <p id="articleAuthor" class="text-sm font-medium text-gray-900">张伟</p>
                                                <p id="authorTitle" class="text-xs text-gray-500">AI产品专家</p>
                                            </div>
                                        </div>
                                    </div>
                                    <div class="flex items-center gap-4 text-sm text-gray-500">
                                        <span><i class="fas fa-eye mr-1"></i><span id="readCount">1,234</span></span>
                                    </div>
                                </div>
                            </div>

                            <!-- 文章内容：初始示例文本会被 JS 动态替换为 Markdown 渲染后的 HTML -->
                            <div id="articleContent" class="prose prose-lg max-w-none">
                                <p class="text-lg text-gray-700 leading-relaxed mb-6">
                                    随着AI技术的快速发展，产品经理的角色也在发生深刻变化。传统的产品经理主要关注功能设计和用户需求，而在AI时代，产品经理需要具备更强的技术理解能力和数据思维。
                                </p>

                                <h2 class="text-2xl font-bold text-gray-900 mb-4">核心技能要求</h2>

                                <h3 class="text-xl font-semibold text-gray-900 mb-3">1. 技术理解能力</h3>
                                <ul class="list-disc list-inside text-gray-700 mb-6 space-y-2">
                                    <li>了解机器学习的基本原理</li>
                                    <li>掌握常见AI算法的应用场景</li>
                                    <li>理解AI模型的局限性</li>
                                </ul>

                                <h3 class="text-xl font-semibold text-gray-900 mb-3">2. 数据思维</h3>
                                <ul class="list-disc list-inside text-gray-700 mb-6 space-y-2">
                                    <li>数据驱动的决策方法</li>
                                    <li>A/B测试设计</li>
                                    <li>用户行为分析</li>
                                </ul>

                                <h3 class="text-xl font-semibold text-gray-900 mb-3">3. 用户体验设计</h3>
                                <ul class="list-disc list-inside text-gray-700 mb-6 space-y-2">
                                    <li>AI产品的交互设计</li>
                                    <li>用户反馈机制</li>
                                    <li>错误处理策略</li>
                                </ul>

                                <h2 class="text-2xl font-bold text-gray-900 mb-4">成长路径</h2>

                                <h3 class="text-xl font-semibold text-gray-900 mb-3">初级阶段（0-1年）</h3>
                                <ul class="list-disc list-inside text-gray-700 mb-6 space-y-2">
                                    <li>学习AI基础知识</li>
                                    <li>参与AI项目实践</li>
                                    <li>建立技术理解</li>
                                </ul>

                                <h3 class="text-xl font-semibold text-gray-900 mb-3">中级阶段（1-3年）</h3>
                                <ul class="list-disc list-inside text-gray-700 mb-6 space-y-2">
                                    <li>独立负责AI产品</li>
                                    <li>优化产品策略</li>
                                    <li>团队协作能力</li>
                                </ul>

                                <h3 class="text-xl font-semibold text-gray-900 mb-3">高级阶段（3年以上）</h3>
                                <ul class="list-disc list-inside text-gray-700 mb-6 space-y-2">
                                    <li>战略规划能力</li>
                                    <li>行业洞察</li>
                                    <li>创新思维</li>
                                </ul>

                                <p class="text-lg text-gray-700 leading-relaxed">
                                    AI产品经理的成长是一个持续学习的过程，需要不断更新知识结构，适应技术发展，同时保持对用户需求的深度理解。
                                </p>
                            </div>

                            <!-- 文章标签：由 JS 根据当前文章 tags 渲染 -->
                            <div class="mt-8 pt-6 border-t border-gray-200">
                                <h4 class="text-sm font-medium text-gray-700 mb-3">文章标签：</h4>
                                <div id="articleTags" class="flex flex-wrap gap-2">
                                    <span class="px-3 py-1 bg-yellow-100 text-yellow-700 text-sm rounded-full">AI产品经理</span>
                                    <span class="px-3 py-1 bg-blue-100 text-blue-700 text-sm rounded-full">职业发展</span>
                                    <span class="px-3 py-1 bg-green-100 text-green-700 text-sm rounded-full">技能提升</span>
                                </div>
                            </div>
                        </article>
                    </div>

                    <!-- 右侧边栏：相关文章 + 公众号二维码 -->
                    <div class="lg:col-span-1">
                        <div class="sticky top-24 space-y-6">
                            <!-- 相关文章：根据同分类或同标签从 blogs 中筛选，最多 3 条 -->
                            <div class="bg-white rounded-xl p-6 shadow-sm">
                                <h3 class="text-lg font-bold text-gray-900 mb-4 flex items-center">
                                    <i class="fas fa-link text-blue-500 mr-2"></i>相关文章
                                </h3>
                                <div id="relatedArticlesSidebar" class="space-y-4">
                                    <!-- 相关文章将通过JavaScript动态生成 -->
                                </div>
                            </div>

                            <!-- 公众号二维码：从 config.wechatOfficialQR 动态加载图片 -->
                            <div class="bg-gradient-to-br from-primary to-yellow-400 rounded-xl p-6 text-center">
                                <div class="w-16 h-16 bg-white/20 rounded-full flex items-center justify-center mx-auto mb-4">
                                    <i class="fab fa-weixin text-white text-2xl"></i>
                                </div>
                                <!-- <h3 class="text-lg font-bold text-gray-900 mb-2">关注公众号</h3> -->
                                <!-- <p class="text-sm text-gray-700 mb-4">扫码关注，获取最新AI行业洞察</p> -->
                                <div class="bg-white rounded-lg p-4 mb-4">
                                    <div id="wechat-qr-container" class="w-32 h-32 bg-gray-200 rounded-lg mx-auto flex items-center justify-center">
                                        <i class="fas fa-qrcode text-gray-400 text-4xl"></i>
                                    </div>
                                    <p class="text-xs text-gray-600 mt-2">公众号二维码</p>
                                </div>
                                <p class="text-xs text-gray-700">扫码关注 lumina AI</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </main>

    <!-- 页脚：站点描述与 ICP 号由通用脚本/配置渲染 -->
    <footer class="bg-gray-50 text-gray-500 py-8 border-t border-gray-200">
        <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
            <div class="mb-2 text-base font-semibold text-gray-700 site-description"></div>
            <div class="text-xs text-gray-400 icp-number"></div>
        </div>
    </footer>

    <!-- JavaScript -->
    <script src="../assets/js/common.js"></script>
    <script>
        // 内嵌配置信息：作为 ../config.json 的兜底，字段相同将被覆盖
        // 字段说明：
        // - icp: 备案号；siteName: 站点名称；description: 站点描述；version: 版本
        // - wechatOfficialQR: 公众号二维码相对路径（相对 frontend/ 根的路径）
        // - knowledgePlanetQR/personalWechatQR: 其他二维码资源（本页未使用）
        const embeddedConfig = {
            "icp": "粤ICP备2024000000号-1",
            "siteName": "lumina AI",
            "description": "让 AI 学习变得简单有趣，一起探索人工智能的无限可能",
            "version": "1.0.0",
            "wechatOfficialQR": "assets/img/wechat-official-qr.png",
            "knowledgePlanetQR": "assets/img/knowledge-planet-qr.png",
            "personalWechatQR": "assets/img/personal-wechat-qr.png"
        };
        // 博客详情管理
        /**
         * 博客详情页控制器
         * - 负责加载 Blogs.json 与 config.json
         * - 渲染面包屑、文章头信息、正文、标签、相关文章与二维码
         * - 使用 localStorage 模拟阅读量持久化
         */
        class BlogDetailManager {
            constructor() {
                this.blogs = [];
                this.currentBlog = null;
                this.blogId = this.getBlogIdFromUrl();
                this.config = null;
            }

            // 从URL获取博客ID
            /**
             * 从 URL 查询参数中获取 blog id（?id=）
             * @returns {number} 当前文章 ID，默认 1
             */
            getBlogIdFromUrl() {
                const urlParams = new URLSearchParams(window.location.search);
                return parseInt(urlParams.get('id')) || 1;
            }

            // 加载博客数据
            /**
             * 并行加载 Blogs.json 与 config.json，合并配置并初始化渲染
             * - 成功后：恢复阅读量 -> 渲染详情与侧栏 -> 加载二维码与 Markdown 正文
             * @returns {Promise<void>}
             */
            async loadBlogData() {
                try {
                    console.log('开始加载数据...');
                    
                    // 并行加载博客数据和配置文件
                    const [blogResponse, configResponse] = await Promise.all([
                        fetch('./Blogs.json'),
                        fetch(`../config.json?t=${Date.now()}`)
                    ]);
                    
                    console.log('配置文件响应状态:', configResponse.status);
                    console.log('配置文件响应头:', configResponse.headers);
                    
                    const blogData = await blogResponse.json();
                    const configText = await configResponse.text();
                    console.log('配置文件原始文本:', configText);
                    
                    try {
                        const loadedConfig = JSON.parse(configText);
                        console.log('解析后的配置:', loadedConfig);
                        // 使用内嵌配置作为备用
                        this.config = { ...embeddedConfig, ...loadedConfig };
                        console.log('最终使用的配置:', this.config);
                    } catch (parseError) {
                        console.error('配置文件解析失败:', parseError);
                        this.config = embeddedConfig;
                        console.log('使用内嵌配置:', this.config);
                    }
                    
                    this.blogs = blogData.blogs || [];
                    
                    // 恢复阅读量数据
                    this.restoreReadCounts();
                    
                    this.loadBlogDetail();
                    this.loadQRCode();
                } catch (error) {
                    console.error('加载数据失败:', error);
                }
            }

            // 加载博客详情
            /**
             * 根据当前 blogId 选择文章，找不到则回退到第一篇
             * - 自增阅读量并持久化到 localStorage
             * - 渲染文章信息、标签、相关文章，并开始加载 Markdown 正文
             */
            loadBlogDetail() {
                this.currentBlog = this.blogs.find(blog => blog.id === this.blogId);
                if (!this.currentBlog) {
                    this.currentBlog = this.blogs[0]; // 默认显示第一篇文章
                }
                
                // 增加阅读量
                this.incrementReadCount(this.blogId);
                
                this.renderBlogDetail();
                this.renderRelatedArticlesSidebar();
                
                // 加载Markdown内容
                this.loadMarkdownContent();
            }

            // 加载Markdown内容
            /**
             * 加载并渲染 Markdown 正文
             * - 优先使用 currentBlog.contentFile 的远程文本
             * - 失败回退到 currentBlog.content 或提示失败
             * @returns {Promise<void>}
             */
            async loadMarkdownContent() {
                if (!this.currentBlog || !this.currentBlog.contentFile) return;
                
                // 显示加载状态
                const contentElement = document.getElementById('articleContent');
                if (contentElement) {
                    contentElement.innerHTML = '<div class="flex items-center justify-center py-8"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div><span class="ml-2 text-gray-600">加载中...</span></div>';
                }
                
                try {
                    const response = await fetch(this.currentBlog.contentFile);
                    if (response.ok) {
                        const markdownContent = await response.text();
                        contentElement.innerHTML = this.formatContent(markdownContent);
                    } else {
                        console.warn('无法加载Markdown文件，使用默认内容');
                        contentElement.innerHTML = this.formatContent(this.currentBlog.content || '内容加载失败');
                    }
                } catch (error) {
                    console.error('加载Markdown内容失败:', error);
                    contentElement.innerHTML = this.formatContent(this.currentBlog.content || '内容加载失败');
                }
            }

            // 渲染博客详情
            /**
             * 将 currentBlog 的关键信息渲染到页面元素
             * - 面包屑、分类颜色、作者头像颜色、阅读量格式化、标签
             */
            renderBlogDetail() {
                if (!this.currentBlog) return;

                // 更新面包屑
                document.getElementById('breadcrumbTitle').textContent = this.currentBlog.title;

                // 更新文章信息
                document.getElementById('articleCategory').textContent = this.currentBlog.category;
                document.getElementById('articleDate').textContent = this.currentBlog.publishDate;
                document.getElementById('articleTitle').textContent = this.currentBlog.title;
                document.getElementById('articleAuthor').textContent = this.currentBlog.author;
                document.getElementById('authorTitle').textContent = this.currentBlog.authorTitle;
                document.getElementById('readCount').textContent = this.formatNumber(this.currentBlog.readCount);

                // 更新作者头像
                const authorInitial = document.getElementById('authorInitial');
                const authorAvatar = document.getElementById('authorAvatar');
                if (authorInitial && authorAvatar) {
                    authorInitial.textContent = this.currentBlog.author.charAt(0);
                    // 根据作者设置头像颜色
                    const authorColorClass = this.getAuthorColorClass(this.currentBlog.author);
                    authorAvatar.className = `w-10 h-10 bg-gradient-to-br ${authorColorClass.bg} rounded-full flex items-center justify-center`;
                    authorInitial.className = `${authorColorClass.text} font-medium text-sm`;
                }

                // 更新分类颜色
                const categoryElement = document.getElementById('articleCategory');
                const colorClass = this.getCategoryColorClass(this.currentBlog.category);
                categoryElement.className = `px-3 py-1 ${colorClass.bg} ${colorClass.text} text-sm rounded-full`;

                // 更新文章内容
                // document.getElementById('articleContent').innerHTML = this.formatContent(this.currentBlog.content); // This line is now handled by loadMarkdownContent

                // 更新文章标签
                this.renderArticleTags();
            }

            // 渲染文章标签
            /**
             * 根据 currentBlog.tags 渲染彩色标签列表
             */
            renderArticleTags() {
                const tagsContainer = document.getElementById('articleTags');
                if (!tagsContainer) return;

                const tagColors = [
                    'bg-yellow-100 text-yellow-700 hover:bg-yellow-200',
                    'bg-blue-100 text-blue-700 hover:bg-blue-200',
                    'bg-green-100 text-green-700 hover:bg-green-200',
                    'bg-purple-100 text-purple-700 hover:bg-purple-200',
                    'bg-pink-100 text-pink-700 hover:bg-pink-200',
                    'bg-indigo-100 text-indigo-700 hover:bg-indigo-200',
                    'bg-red-100 text-red-700 hover:bg-red-200',
                    'bg-orange-100 text-orange-700 hover:bg-orange-200',
                    'bg-teal-100 text-teal-700 hover:bg-teal-200',
                    'bg-gray-100 text-gray-700 hover:bg-gray-200'
                ];

                tagsContainer.innerHTML = this.currentBlog.tags.map((tag, index) => {
                    const colorClass = tagColors[index % tagColors.length];
                    return `<span class="px-3 py-1 ${colorClass} text-sm rounded-full">${tag}</span>`;
                }).join('');
            }

            // 格式化内容
            /**
             * 使用简化的 Markdown 规则将文本转换为 HTML 片段
             * - 识别 ##、###、与以 "- " 开头的列表
             * - 其余渲染为段落
             * - 特殊支持：
             *   1) ```svg ... ``` 栅栏代码块将直接作为 SVG 注入
             *   2) Markdown 图片语法 ![alt](url.svg|png|jpg|gif|webp) 自动转换为 <img>
             *   3) 含有 <svg> 的段落直接原样注入，避免被 <p> 包裹
             * @param {string} content 原始 Markdown 文本
             * @returns {string} HTML 字符串
             */
            formatContent(content) {
                // 预处理：将 ```svg ... ``` 栅栏代码块直接展开为内联 SVG
                let processed = content
                    // 处理 ```svg ... ```
                    .replace(/```svg[\r\n]+([\s\S]*?)```/g, (match, svgInner) => svgInner.trim())
                    // 将 Markdown 图片语法转为 <img>
                    .replace(/!\[(.*?)\]\((.*?)\)/g, (m, alt, src) => {
                        return `<img src="${src}" alt="${alt}" class="mx-auto my-4 rounded-lg" />`;
                    });

                // 提取并占位所有 <svg>...</svg> 块，避免按空行拆分时被打断
                const svgBlocks = [];
                processed = processed.replace(/<svg[\s\S]*?<\/svg>/g, (m) => {
                    // 标准化 SVG：确保可见区域不被裁剪与等比缩放
                    let normalized = m
                        // 去掉硬编码的宽高，改为 CSS 控制自适应
                        .replace(/\swidth=\"[^\"]*\"/g, '')
                        .replace(/\sheight=\"[^\"]*\"/g, '');
                    // 若无 preserveAspectRatio，添加 meet 以保持完整显示
                    if (!/preserveAspectRatio=\"[^\"]*\"/.test(normalized)) {
                        normalized = normalized.replace(
                            /<svg(\s+)/,
                            '<svg$1preserveAspectRatio="xMidYMid meet" '
                        );
                    }
                    // 确保不被裁剪
                    if (!/\soverflow=\"[^\"]*\"/.test(normalized)) {
                        normalized = normalized.replace(
                            /<svg(\s+)/,
                            '<svg$1overflow="visible" '
                        );
                    }
                    const idx = svgBlocks.push(normalized) - 1;
                    return `@@SVG_BLOCK_${idx}@@`;
                });

                // 将Markdown格式转换为HTML
                return processed
                    .split('\n\n')
                    .map(paragraph => {
                        const trimmed = paragraph.trim();
                        // 原样注入 SVG 或已转换的 <img>
                        if (trimmed.startsWith('<svg') || trimmed.includes('</svg>')) {
                            return `<div class="my-4">${trimmed}</div>`;
                        }
                        if (trimmed.startsWith('<img') || trimmed.includes('<img ')) {
                            return trimmed;
                        }
                        if (paragraph.startsWith('## ')) {
                            return `<h2 class="text-2xl font-bold text-gray-900 mb-4">${paragraph.substring(3)}</h2>`;
                        } else if (paragraph.startsWith('### ')) {
                            return `<h3 class="text-xl font-semibold text-gray-900 mb-3">${paragraph.substring(4)}</h3>`;
                        } else if (paragraph.startsWith('- ')) {
                            const items = paragraph.split('\n').filter(item => item.startsWith('- '));
                            const listItems = items.map(item => `<li class="text-gray-700">${item.substring(2)}</li>`).join('');
                            return `<ul class="list-disc list-inside text-gray-700 mb-6 space-y-2">${listItems}</ul>`;
                        } else if (paragraph.trim() === '') {
                            return '';
                        } else {
                            return `<p class="text-lg text-gray-700 leading-relaxed mb-6">${paragraph}</p>`;
                        }
                    })
                    .filter(html => html.trim() !== '')
                    .join('');
            }

            // 获取分类颜色类
            /**
             * 根据分类名称返回颜色类（用于徽标）
             * @param {string} category 分类名
             * @returns {{bg:string, text:string}} Tailwind 类组合
             */
            getCategoryColorClass(category) {
                const categoryMap = {
                    '产品思考': { bg: 'bg-yellow-100', text: 'text-yellow-700' },
                    '技术实践': { bg: 'bg-blue-100', text: 'text-blue-700' },
                    '硬件分析': { bg: 'bg-green-100', text: 'text-green-700' },
                    '安全伦理': { bg: 'bg-purple-100', text: 'text-purple-700' },
                    '行业趋势': { bg: 'bg-pink-100', text: 'text-pink-700' },
                    '学习资源': { bg: 'bg-indigo-100', text: 'text-indigo-700' },
                    '项目实战': { bg: 'bg-orange-100', text: 'text-orange-700' },
                    '产品创新': { bg: 'bg-yellow-100', text: 'text-yellow-700' }
                };
                return categoryMap[category] || { bg: 'bg-gray-100', text: 'text-gray-700' };
            }

            // 格式化数字
            /**
             * 将大于等于 1000 的数字格式化为 1.2k 形式
             * @param {number} num 原始数字
             * @returns {string}
             */
            formatNumber(num) {
                if (num >= 1000) {
                    return (num / 1000).toFixed(1) + 'k';
                }
                return num.toString();
            }

            // 渲染相关文章（侧边栏）
            /**
             * 生成相关文章列表（同分类或同标签优先；否则热门/精选；否则任意）
             */
            renderRelatedArticlesSidebar() {
                const relatedArticlesSidebar = document.getElementById('relatedArticlesSidebar');
                if (!relatedArticlesSidebar || !this.currentBlog) return;

                // 获取相关文章（同分类或同标签）
                let relatedBlogs = this.blogs
                    .filter(blog => blog.id !== this.currentBlog.id)
                    .filter(blog => 
                        blog.category === this.currentBlog.category ||
                        blog.tags.some(tag => this.currentBlog.tags.includes(tag))
                    );

                // 如果没有找到相关文章，显示其他热门文章
                if (relatedBlogs.length === 0) {
                    relatedBlogs = this.blogs
                        .filter(blog => blog.id !== this.currentBlog.id)
                        .filter(blog => blog.isHot || blog.isFeatured);
                }

                // 如果还是没有，显示除当前文章外的其他文章
                if (relatedBlogs.length === 0) {
                    relatedBlogs = this.blogs.filter(blog => blog.id !== this.currentBlog.id);
                }

                relatedBlogs = relatedBlogs.slice(0, 3); // 只显示3条相关文章


                
                relatedArticlesSidebar.innerHTML = relatedBlogs.map(blog => {
                    const iconColorClass = this.getIconColorClass(blog.iconColor);
                    return `
                        <a href="blog-detail.html?id=${blog.id}" class="block group">
                            <div class="flex items-start gap-3">
                                <div class="w-12 h-12 bg-gradient-to-br ${iconColorClass.bg} rounded-lg flex items-center justify-center flex-shrink-0">
                                    <i class="${blog.icon} ${iconColorClass.text} text-sm"></i>
                                </div>
                                <div class="flex-1 min-w-0">
                                    <h4 class="text-sm font-medium text-gray-900 group-hover:text-primary transition-colors line-clamp-2">
                                        ${blog.title}
                                    </h4>
                                    <p class="text-xs text-gray-500 mt-1">${this.formatNumber(blog.readCount)} 阅读</p>
                                </div>
                            </div>
                        </a>
                    `;
                }).join('');
            }



            // 获取图标颜色类
            /**
             * 根据配置色名返回渐变背景与文字色
             * @param {string} color 颜色键（yellow/blue/green/...）
             * @returns {{bg:string, text:string}}
             */
            getIconColorClass(color) {
                const colorMap = {
                    'yellow': { bg: 'from-yellow-100 to-yellow-200', text: 'text-yellow-600' },
                    'blue': { bg: 'from-blue-100 to-blue-200', text: 'text-blue-600' },
                    'green': { bg: 'from-green-100 to-green-200', text: 'text-green-600' },
                    'purple': { bg: 'from-purple-100 to-purple-200', text: 'text-purple-600' },
                    'pink': { bg: 'from-pink-100 to-pink-200', text: 'text-pink-600' },
                    'indigo': { bg: 'from-indigo-100 to-indigo-200', text: 'text-indigo-600' },
                    'orange': { bg: 'from-orange-100 to-orange-200', text: 'text-orange-600' }
                };
                return colorMap[color] || colorMap['blue'];
            }

            // 获取作者颜色类
            /**
             * 根据作者名称返回头像背景/文字颜色类
             * @param {string} authorName 作者名
             * @returns {{bg:string, text:string}}
             */
            getAuthorColorClass(authorName) {
                const authorColorMap = {
                    '张伟': { bg: 'from-blue-100 to-blue-200', text: 'text-blue-600' },
                    '李娜': { bg: 'from-green-100 to-green-200', text: 'text-green-600' },
                    '王磊': { bg: 'from-purple-100 to-purple-200', text: 'text-purple-600' },
                    '赵敏': { bg: 'from-purple-100 to-purple-200', text: 'text-purple-600' },
                    '陈晨': { bg: 'from-pink-100 to-pink-200', text: 'text-pink-600' },
                    '孙洋': { bg: 'from-indigo-100 to-indigo-200', text: 'text-indigo-600' },
                    '周婷': { bg: 'from-orange-100 to-orange-200', text: 'text-orange-600' },
                    '刘强': { bg: 'from-yellow-100 to-yellow-200', text: 'text-yellow-600' }
                };
                return authorColorMap[authorName] || { bg: 'from-gray-100 to-gray-200', text: 'text-gray-600' };
            }

            // 增加阅读量
            /**
             * 将当前文章阅读量+1，并将所有文章的 id/readCount 存入 localStorage
             * @param {number} blogId 文章 ID
             */
            incrementReadCount(blogId) {
                const blog = this.blogs.find(b => b.id === blogId);
                if (blog) {
                    blog.readCount++;
                    // 更新本地存储
                    localStorage.setItem('blogReadCounts', JSON.stringify(this.blogs.map(b => ({ id: b.id, readCount: b.readCount }))));
                }
            }

            // 恢复阅读量数据
            /**
             * 从 localStorage 读取历史阅读量并回填到 this.blogs
             */
            restoreReadCounts() {
                const savedReadCounts = localStorage.getItem('blogReadCounts');
                if (savedReadCounts) {
                    try {
                        const readCounts = JSON.parse(savedReadCounts);
                        readCounts.forEach(item => {
                            const blog = this.blogs.find(b => b.id === item.id);
                            if (blog) {
                                blog.readCount = item.readCount;
                            }
                        });
                    } catch (error) {
                        console.error('恢复阅读量数据失败:', error);
                    }
                }
            }

            // 加载二维码
            /**
             * 基于配置渲染公众号二维码图片
             * - 图片路径相对本页：../${config.wechatOfficialQR}
             * - 失败时显示错误提示文本
             */
            loadQRCode() {
                console.log('开始加载二维码...');
                console.log('配置信息:', this.config);
                
                if (!this.config || !this.config.wechatOfficialQR) {
                    console.error('配置信息或二维码路径不存在');
                    return;
                }
                
                // 使用ID选择器
                const qrCodeContainer = document.getElementById('wechat-qr-container');
                console.log('找到的二维码容器:', qrCodeContainer);
                
                if (qrCodeContainer) {
                    const imagePath = `../${this.config.wechatOfficialQR}`;
                    console.log('原始配置路径:', this.config.wechatOfficialQR);
                    console.log('计算后的图片路径:', imagePath);
                    console.log('当前页面URL:', window.location.href);
                    console.log('当前页面路径:', window.location.pathname);
                    
                    // 清空容器并添加图片
                    qrCodeContainer.innerHTML = '';
                    const img = document.createElement('img');
                    img.src = imagePath;
                    img.alt = '微信公众号二维码';
                    img.className = 'w-full h-full object-cover rounded-lg';
                    img.onload = () => {
                        console.log('图片加载成功');
                        qrCodeContainer.style.background = 'none'; // 移除背景色
                    };
                    img.onerror = () => {
                        console.error('图片加载失败:', imagePath);
                        console.error('尝试访问的完整URL:', new URL(imagePath, window.location.href).href);
                        // 如果图片加载失败，显示错误信息
                        qrCodeContainer.innerHTML = '<div class="text-red-500 text-xs">图片加载失败</div>';
                    };
                    qrCodeContainer.appendChild(img);
                } else {
                    console.error('未找到二维码容器元素 (ID: wechat-qr-container)');
                }
            }
        }

        // 全局变量
        let blogDetailManager;

        // 页面加载完成后初始化
        document.addEventListener('DOMContentLoaded', function() {
            blogDetailManager = new BlogDetailManager();
            blogDetailManager.loadBlogData();
        });
    </script>
    <style>
        /* 多行省略工具类：限制为 2 行并截断 */
        .line-clamp-2 {
            display: -webkit-box;
            line-clamp: 2;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
            overflow: hidden;
        }
        /* 文章内容内的图片与 SVG 自适应容器宽度 */
        #articleContent img,
        #articleContent svg {
            max-width: 100%;
            height: auto;
        }
        /* 让内联 SVG 不会溢出容器并有合适的间距 */
        #articleContent svg {
            display: block;
            margin: 1rem auto;
        }
        /* 包裹 SVG 的容器：允许横向滚动，避免剪裁 */
        #articleContent .svg-block {
            overflow-x: auto;
            -webkit-overflow-scrolling: touch;
        }
        /* 若 SVG 内自带宽高，确保不被父容器强行压缩 */
        #articleContent .svg-block svg {
            width: 100%;
            height: auto;
        }
    </style>
</body>
</html>